﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Acoris.Content
{
    using Acoris.Foundation;
    using Acoris.Document;
    using Acoris.Markdown;

    /// <summary>
    /// 表示一组设计在工厂模式的用于创建内容页的API
    /// </summary>
    internal static class ContentFactory
    {
        // this class implement text storage,we use rope data-structure to instead string
        // because we need a high performance data-structure to reduce the time spent
        // when we execute  delete/insert/replace/concat operation  frequently

        // we should cache the some rope data-structure because rebuild the tree-sturecture
        // from flat-string,it will be cost much time

        #region Notebook Collection

        // 该区域编写下列的代码逻辑:
        // 1) 记录用户所有创建的记事本
        // 2) 管理记事本的同步(作为一个新的feature)

        static NotebookFolderCollection notebookFolderCollection = new NotebookFolderCollection();

        /// <summary>
        /// 获取当前记事本保存的目录
        /// </summary>
        public static NotebookFolderCollection NotebookFolder {
            get { return notebookFolderCollection; }
        }

        #endregion

        #region Notebook Scope

        #endregion

        #region Section Scope

        static Stack<Section> m_sectionStack = new Stack<Section>();
        static Dictionary<Section,Rope> m_ropeDictionary = new Dictionary<Section, Rope>();
        const byte SectionStackMaxSize = 8;

        /// <summary>
        /// 开始一个内容分区的生命周期
        /// </summary>
        /// <param name="section"></param>
        internal static void BeginSection(Section section)
        {
            Stack<Section> tempStack = new Stack<Section>();
            if (m_sectionStack.Count == SectionStackMaxSize) {
                // 将不需要结束生命周期的元素移动到指定的堆栈中
                for (int i = 0; i < 4; i++) {
                    var topElement = m_sectionStack.Pop();
                    tempStack.Push(topElement);
                }

                // 清除指定的内容
                var element = m_sectionStack.Pop();
                EndSection(element);

                // 恢复堆栈
                foreach (var e in tempStack) {
                    m_sectionStack.Push(e);
                }
            }

            ParseSection(section);
            ActiveDocument(section);
            m_sectionStack.Push(section);
        }

        /// <summary>
        /// 结束一个内容分区的生命周期
        /// </summary>
        static void EndSection(Section section)
        {
            if (m_ropeDictionary.ContainsKey(section)) {
                m_ropeDictionary.Remove(section);
            }
            InactiveDocument(section);
            section.Dispose(); // 释放资源
        }

        /// <summary>
        /// 解析指定的内容分区
        /// </summary>
        /// <param name="section"></param>
        static void ParseSection(Section section)
        {
            // 将原始AML文档转换为AMLDocument对象
            lock (section.m_lock) {
                var objectWriter = new AMLObjectWriter();
                var amlReader = new AMLReader();
                var rootNode = (AMLParseNode)amlReader.Load(section.m_documentText);
                var document = (AMLDocument)objectWriter.Serialize(rootNode);
                section.m_document = document;
            }
        }

        /// <summary>
        /// 获取当前的焦点内容分区
        /// </summary>
        internal static Section Scope {
            get { return m_sectionStack.Peek(); }
        }

        /// <summary>
        /// 激活当前内容分区的文档
        /// </summary>
        /// <param name="section"></param>
        static void ActiveDocument(Section section)
        {

        }

        /// <summary>
        /// 删除指定内容的文档
        /// </summary>
        /// <param name="section"></param>
        static void InactiveDocument(Section section)
        {
            Rebuild(section);
        }
        #endregion

        #region AmlDocument Load / Save

        // content keywords:
        // 
        // keyword          fullname
        // -----------------------------------------
        // p                paragraph tag
        // img              image tag
        // imgs             image array tag
        // video            video tag
        // audio            audio tag
        // iaction          interaction tag
        // sp               space tag
        // nl               newline tag
        // ---- extension tag
        // geometry         geometry tag
        // 
        static readonly string[] DocumentContentKeyword ={
            "p","img","imgs","video","audio","iaction","sp","nl"
        };

        // rebuild DocumentTree
        static void Rebuild(Section section)
        {
            var document = section.m_document;
            lock (section.m_lock) {
                var contentReader = new AMLContentReader();
                // AMLContent之中保存着内容的树形结构
                // 我们需要把它重建生成一棵文档树
                var documentTree = contentReader.Load(document.content
                                                              .Document) as DocumentTree;
                //
                section.m_document
                       .document = documentTree;
            }
        }

        #endregion

        #region Section Load / Save / Delete

        #endregion

        #region Page Load / Save / Delete

        #endregion

        #region Notebook Load / Save / Delete

        #endregion

        #region NameObjected Rename

        /// <summary>
        /// 重命名
        /// </summary>
        /// <param name="namedObject"></param>
        /// <param name="newName"></param>
        public static void Rename(NamedObject namedObject, string newName)
        {
            namedObject.Name = newName;
        }

        #endregion
    }
}
